package fightplan.views;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;

import fightplan.actions.UndoRedoManager;
import fightplan.actions.UndoRedoManagerProvider;
import fightplan.actions.UndoableAction;
import fightplan.business.AbstractFighter;
import fightplan.business.Category;
import fightplan.core.FPExceptionHandler;
import fightplan.core.Style;

@SuppressWarnings("serial")
public class TeamsPanel extends JPanel implements UndoRedoManagerProvider {
	private TeamsForCategoryTableModel tableModel;

	private JTable table;

	private TableRowSorter<TeamsForCategoryTableModel> sorter;

	protected Category category;

	public TeamsPanel() {
		super(new BorderLayout());

		tableModel = new TeamsForCategoryTableModel();
		table = new JTable(tableModel);
		table.getColumnModel().getColumn(1).setPreferredWidth(100);
		table.getColumnModel().getColumn(1).setMaxWidth(100);

		sorter = new TableRowSorter<TeamsForCategoryTableModel>(tableModel);
		table.setRowSorter(sorter);
		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

		JScrollPane scrollPane = new JScrollPane(table);
		scrollPane.getViewport().setBackground(Style.UNUSED_TABLE_SPACE);
		scrollPane.setPreferredSize(new Dimension(5000, 5000));

		add(scrollPane, BorderLayout.CENTER);
		add(addAction(), BorderLayout.SOUTH);
	}

	public void setCategory(Category category) {
		if (this.category != null) {
			this.category.removeListDataListener(tableModel);
		}

		this.category = category;
		tableModel.updateFighters();

		if (this.category != null) {
			category.addListDataListener(tableModel);
		}
	}

	private int calcSeed(AbstractFighter fighter) {
		int pos = 1;
		for (AbstractFighter seededFighter : category.getSeeds()) {
			if (seededFighter.equals(fighter))
				return pos;
			pos++;
		}
		return 0;
	}

	//

	private class TeamsForCategoryTableModel extends AbstractTableModel implements ListDataListener {

		public TeamsForCategoryTableModel() {
		}

		// ListDateListener

		public void intervalAdded(ListDataEvent e) {
			updateFighters();
		}

		public void intervalRemoved(ListDataEvent e) {
			updateFighters();
		}

		public void contentsChanged(ListDataEvent e) {
			updateFighters();
		}

		public void updateFighters() {
			fireTableDataChanged();
		}

		public int getColumnCount() {
			return 2;
		}

		@Override
		public String getColumnName(int columnIndex) {
			switch (columnIndex) {
			case 0:
				return "Name";
			case 1:
				return "Gesetzte Position";
			}
			return null;
		}

		public Object getValueAt(int rowIndex, int columnIndex) {
			AbstractFighter fighter = category.getFighters().get(rowIndex);
			switch (columnIndex) {
			case 0:
				return fighter.getName();
			case 1:
				return calcSeed(fighter);
			}
			return null;
		}

		public int getRowCount() {
			return category != null ? category.getFighters().size() : 0;
		}

	}

	private JPanel addAction() {
		JPanel panel = new JPanel(new FlowLayout(SwingConstants.RIGHT));
		panel.add(createSeedButton());
		return panel;
	}

	private JButton createSeedButton() {
		final Action seedAction = new UndoableAction("Setzen", this, "Setzen rückgängig machen") {
			public boolean doAction(ActionEvent e) {
				if (category.isPlanned()) {
					FPExceptionHandler.instance().showInformation("Kategorie bereits ausgelost.",
							"Keine Änderung möglich");
					return false;
				}

				AbstractFighter fighter = category.getFighters().get(
						table.convertRowIndexToModel(table.getSelectedRow()));
				int valueCount = category.getSeeds().size() + 1;
				int seed = calcSeed(fighter);
				if (seed > 0)
					valueCount--;
				Object[] selectionValues = new Object[valueCount + 1];
				selectionValues[0] = "Ungesetzt";
				for (int i = 1; i <= valueCount; i++) {
					selectionValues[i] = i;
				}

				Object initialSelectionValue;
				if (seed > 0) {
					initialSelectionValue = seed;
				} else {
					initialSelectionValue = "Ungesetzt";
				}

				Object result = JOptionPane.showInputDialog(TeamsPanel.this, "Auf welche Position setzen?",
						"Position setzen", JOptionPane.QUESTION_MESSAGE, null, selectionValues, initialSelectionValue);

				if (result == null)
					return false;
				if (result == "Ungesetzt")
					result = 0;

				//

				category.getSeeds().remove(fighter);
				int newPos = (Integer) result;
				if (newPos > 0) {
					newPos = newPos - 1; // List count starts at 0
					if (newPos > category.getSeeds().size()) {
						newPos = category.getSeeds().size();
					}
					category.getSeeds().add(newPos, fighter);
				}

				table.repaint();
				return true;
			}
		};

		seedAction.setEnabled(table.getSelectedRows().length == 1);
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				seedAction.setEnabled(table.getSelectedRows().length == 1);
			}
		});
		return new JButton(seedAction);
	}

	public UndoRedoManager getUndoRedoManager() {
		return ((MainView) SwingUtilities.getWindowAncestor(this)).getUndoRedoManager();
	}

}
